<template>
  <div class="h-dropdown">
    <div class="h-dropdown-header" ref="dropdownHeader">
      <renderTitle/>
    </div>

    <div @click="close" class="h-dropdown-overlayer" v-show="showOverlayer" :style="overlayerStyle">
      <template v-for="item in children">
        <div @click.stop class="h-dropdown-body" ref="dropDownBodyWrapper" v-show="item.value === props.show">
          <renderItemBody :item="item"/>
        </div>
      </template>
    </div>
    {{rendered()}}
  </div>
</template>
<script setup>
import {closePopup, createProps, pushPopup} from '@/utils';
import {computed, h, nextTick, ref, shallowRef, useSlots, watch} from 'vue';
import {Icon} from 'vant';

defineOptions({name: 'HDropdown'});

const slots = useSlots();
const dropdownHeader = shallowRef();
const props = defineProps({
  show: createProps(String),
});
const emits = defineEmits(['update:show']);
const overlayerStyle = ref({});
const dropDownBodyWrapper = shallowRef();

function renderTitle() {
  let list = getChildren() || [];
  return list.map((item, index) => {
    return doRenderTitle(item);
  });
}

function getBody(item) {
  try {
    return item?.vnode?.children?.default();
  } catch (e) {
    console.error(e);
  }
  return [];
}

function rendered() {
  nextTick(() => {
    let list = dropDownBodyWrapper.value || [];
    for (let i = 0; i < list.length; i++) {
      let item = list[i];
      item.style.height = undefined
      nextTick(() => {
        let rect = item.getBoundingClientRect();
        item.style.height = rect.height && `${rect.height}px` || 'fit-content';
      })
    }

  })
}

function renderItemBody({item}) {
  let body = getBody(item);
  return body;
}

function getChildren() {
  let list = slots.default();
  let res = [];
  list.forEach(item => {
    if (item?.type?.name === 'HDropdownItem') return res.push(item);
    if (typeof item?.type === 'function') {
      let temp = item.type();
      temp.forEach(t => {
        if (t.type.name === 'HDropdownItem') {
          res.push(t);
        }
      })
    }
  });
  return res;
}

const children = computed(() => {
  let res = [];
  let list = getChildren() || [];
  list.forEach((item, index) => {
    res.push({
      title: getTitle(item),
      vnode: item,
      value: getValue(item),
    });
  });
  return res;
});

const showOverlayer = computed(() => {
  try {
    let list = getChildren() || [];
    return !!(list.find(item => {
      return getValue(item) === props.show;
    }));
  } catch (error) {
  }
  return false;
});

watch(() => showOverlayer.value, () => {
  nextTick(() => {
    if (showOverlayer.value) {
      opened();
    }
  });
});

function opened() {
  let rect = dropdownHeader.value.getBoundingClientRect();
  overlayerStyle.value.height = `calc(100vh - ${rect.bottom}px)`;
  pushPopup({
    close: () => {
      doClose();
    }
  });
}

function doClose() {
  emits('update:show', false);
}

const showItem = computed(() => {
  try {
    let list = getChildren() || [];
    return list.find(item => {
      return getValue(item) === props.show;
    });
  } catch (error) {
  }
  return undefined;
});

function getTitle(item) {
  if (item?.children?.title) {
    return item.children.title();
  }
  // return item?.props?.title;
  return h('div', {
    class: 'h-dropdown-item-title-text',
  }, [item?.props?.title]);
}

function getValue(item) {
  return item?.props?.value;
}

function doRenderTitle(item) {
  let title = getTitle(item);
  if (!title) return undefined;
  return h('div', {
    class: ['h-dropdown-item-title', {'h-dropdown-item-title-primary': getValue(item) === props.show}],
    onClick: () => {
      changeShow(item);
    }
  }, [title, renderArrow(item)]);
}

function changeShow(item) {
  let itemValue = getValue(item);
  if (itemValue === props.show) {
    //需要关闭
    close();
  } else {
    emits('update:show', getValue(item));
  }
}

function close() {
  closePopup();
}

function renderArrow(item) {
  let transform = undefined;
  if (getValue(item) === props.show) {
    transform = 'rotate(180deg)';
  }
  return h(Icon, {
    name: 'arrow-up',
    class: 'icon',
    style: {
      transform
    }
  });
}

</script>
<style lang="less">
.h-dropdown {
}

.h-dropdown-header {
  display: flex;
  z-index: 3000;
  border-bottom: 1px solid var(--van-border-color);
  width: 100vw;
}

.h-dropdown-overlayer {
  background: rgba(0, 0, 0, 0.7);
  position: fixed;
  width: 100vw;
  z-index: 3000;
  animation: h-dropdown-overlayer-show 0.5s;
}

.h-dropdown-item-title-primary {
  color: var(--van-primary-color);
}

.h-dropdown-item-title:active {
  color: var(--van-primary-color);
  background: var(--van-gray-1);
}

.h-dropdown-item-title .icon {
  //transition: transform 0.2s ease;
  margin-left: 10px;
}

.h-dropdown-item-title {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.14rem;
  flex: 1;
  overflow: hidden;
  border-top: 1px solid var(--van-border-color);
  border-bottom: 1px solid var(--van-border-color);
}

.h-dropdown-item-title-text {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
  font-size: 0.14rem;
  width: 10px;
}

.h-dropdown-item-title:not(:last-child) {
  border-right: 1px solid var(--van-border-color);
}

.h-dropdown-item-title {
  background: var(--van-white);
  flex: 1;
  padding: 0.1rem 0.05rem;
  text-align: center;
}

@keyframes h-dropdown-overlayer-show {
  0% {
    background: rgba(0, 0, 0, 0);
  }
  100% {
    background: rgba(0, 0, 0, 0.7);
  }
}

.h-dropdown-body {
  height: fit-content;
  max-height: 100%;
  overflow: auto;
  background: var(--van-white);
  animation: h-dropdown-body 0.2s forwards;
  z-index: 10;
}

@keyframes h-dropdown-body {
  0% {
    opacity: 0.7;
    margin-top: -5px;
  }
  100% {
    opacity: 1;
    margin-top: 0;
  }
}
</style>